#ifndef COLLISION_WORLD_H
#define COLLISION_WORLD_H

#include <vector>
#include <list>
using namespace std;

#include "Line.h"
#include "IntersectionDetection.h"
#include "QuadTree.h"
#include <cilk/reducer_list.h>
#include <cilk/reducer_opadd.h>

struct IntersectionInfo {
  Line *l1, *l2;
  IntersectionType intersectionType;

  IntersectionInfo(Line *l1, Line *l2, IntersectionType intersectionType) {
    this->l1 = l1;
    this->l2 = l2;
    this->intersectionType = intersectionType;
  }
};

class CollisionWorld
{
protected:
   // The size of the collision world
   int boxWidth;
   int boxHeight;

   // Time step used for simulation
   double  timeStep;

   // Container holding all the lines
   vector<Line*> lines;
   cilk::reducer_list_append<IntersectionInfo*> *intersections;
   cilk::reducer_list_append<Line*> *bad_lines;

   // Record the total number of line wall collision
   unsigned int numLineWallCollisions;

   // Record the total number of line line intersection
   unsigned int numLineLineCollisions;
   
   // Record the number of intersection tests for analysis
   cilk::reducer_opadd<int> *numIntersectionTests;

   QuadTree *qt;

public:
   CollisionWorld();
   ~CollisionWorld();

   // Return the total number of lines in the box
   unsigned int getNumOfLines();

   // Add a line into the box
   void  addLine(Line *line);
  
   void  preprocessLines();

   // Get a line from box
   Line *getLine(unsigned int index);

   // Delete all lines in the box
   void  deleteLines();

   // Update lines' situation in the box
   void  updateLines();

   // Update position of lines
   void  updatePosition();
   
   // Update quadtree
   void updateQuadTree();
   void updateNode(QuadTree*);

   // Handle line wall collision
   void lineWallCollision();

   // Detect Line Line intersection
   void  detectIntersection();
   // Helper function that recursively find intersections in a quadtree
   void detectIntersectionsOnQuadTree(QuadTree*);
  // Finds all intersections in this quadtree node
  void bruteForceIntersections(QuadTree*, int, int);

   // Get total number of line wall collisions
   unsigned int getNumLineWallCollisions();

   // Get total number of line line intersection
   unsigned int getNumLineLineCollisions();

   void collisionSolver(Line *l1, Line *l2, IntersectionType intersectionType);
};



#endif  /* COLLISION_WORLD_H */
